const {
	Service
} = require('uni-cloud-router');
const {
	parser,
	success,
	exception,
	error,
	typeOf,
	Clock,
	timingLogger,
	StatusEnum,
	DictItem,
	processCallFunResult,
	isNumber,
	isArray,
	isObject
} = require("lg-utils");
const {
	forEachCollection,
	getCollForAllByField
} = require("lg-utils-db");
const db = uniCloud.database();
const dbCmd = db.command;
const STOCK_BASE_COLL = db.collection("stock-base");
module.exports = class CommonService extends Service {
	async xxx() {
		try {
			return await "xxxxxxx"
		} catch (e) {
			throw e
		}

	}
	// 获取指定返回字段的所有stock对象;
	async getStockBaseAllByFields(field = {}) {
		try {
		  return await getCollForAllByField({
				collection:STOCK_BASE_COLL,
				field
			});
		} catch (e) {
			throw e;
		}

	}
	async addIterWithStock(inser = {}) {
		try {
			let insertArr = [];
			if (isArray(inser)) {
				insertArr = inser
			} else {
				insertArr = [inser];
			}

			const {
				inserted
			} = await STOCK_BASE_COLL.add(insertArr) || {};
			if (isNumber(inserted)) {
				return success(inserted);
			} else {
				return error("stock集合新增数据异常;");
			}

		} catch (e) {
			throw e;
		}

	}

	async updateStockInfoToDiff() {
		try {
			console.log(">>>>");
			const {
				ctx,
				service
			} = this;
			return await service.line.addIterForDay("6666");

			const successList = [];
			const failedList = [];
			// 远程调取 基金信息
			const {
				result: {
					data: {
						stockTotalList: remoteStockList,
						symbolList: remoteSymbolList,
						count: remoteSymbolListCount
					} = {},
					success: catchSucc,
					errorMessage: catchErro
				} = {},
				success: catchReqSucc
			} = await uniCloud.callFunction({
				name: "capture",
				data: {
					action: "stock/catchStockBaseInfoList"
				}
			}) || {};

			if (catchReqSucc) {
				if (catchSucc) {
					// 获取 字典symbolList 
					const {
						result: {
							data: symbols,
							success: symbolsSucc,
							errorMessage: symbolsErro
						} = {},
						success: symbolsReqSucc
					} = await uniCloud.callFunction({
						name: "dictionary",
						data: {
							action: "common/getDictDataByType",
							data: "stockSymbolList"
						}
					})

					if (symbolsReqSucc) {
						if (symbolsSucc) {


							const pageUpdateSize = 100;
							const updatePromises = [];
							for (let [index, value] of Object.entries(remoteStockList)) {

								const {
									symbol
								} = value || {};
								if (symbols.includes(symbol)) {
									const preInster = {
										...value,
										update_dt: Clock.now()
									}
									updatePromises.push(this.updateBaseInfoListWithStockByWhere({
										where: {
											symbol
										},
										content: preInster
									}));
								} else {
									const {
										data: insterData,
										success: insterSucc,
										errorMessage: insterErrMsg
									} = await this.insertStockAndSymbol(value) || {};
									if (insterSucc) {
										successList.push(insterData);
									} else {
										failedList.push({
											symbol,
											err: insterErrMsg
										});
									}

								}

								const curIndex = Number.parseInt(index) + 1;
								if ((curIndex % pageUpdateSize) === 0 || curIndex === remoteSymbolListCount) {
									try {

										const res = await Promise.all(updatePromises);
										for (let i = 0; i < res.length; i++) {
											const {
												data: resSymbol,
												success: resSucc,
												errorMessage: resErrMsg,
												exceptionData: resExpData
											} = res[i] || {};
											if (resSucc) {
												successList.push(resSymbol);
											} else {
												failedList.push({
													symbol: resExpData,
													errorMessage: resErrMsg
												})
											}
										}
										updatePromises.length = 0;
										console.log(remoteSymbolListCount, ">", curIndex);
									} catch (e) {
										return error("循环更新stock信息异常;", e);
									}
								}

							}
							return success({
								updateCount: successList.length,
								failedList
							});
						} else {
							return error(symbolsErro);
						}
					} else {
						return error("获取基金symbol集合请求异常;");
					}

				} else {
					return error(catchErro);
				}
			} else {
				return error("捕获基金信息列表请求异常;");
			}

		} catch (e) {
			throw e
		}

	}

	// 新添加到stock集合, 更新 symbolList字典 
	async insertStockAndSymbol(stock) {
		try {
			const {
				symbol
			} = stock || {};
			const nowdt = Clock.now();
			let exchange_code = "";
			let exchange_name = "";
			if (symbol.startsWith("sh")) {
				exchange_code = "sh";
				exchange_name = "上海证券交易所";
			} else if (symbol.startsWith("sz")) {
				exchange_code = "sz";
				exchange_name = "深圳证券交易所";
			}
			const preStock = {
				...stock,
				start_dt: nowdt,
				update_dt: nowdt,
				exchange_code,
				exchange_name
			};

			const {
				data: addData,
				success: addSucc,
				errorMessage: addErr
			} = await this.addIterWithStock(preStock);
			if (addSucc) {
				const {
					result: {
						data: dictData,
						success: dictSucc
					}
				} = await uniCloud.callFunction({
					name: "dictionary",
					data: {
						action: "common/updateIterPushDateByType",
						data: {
							type: "stockSymbolList",
							data: symbol
						}
					}
				});
				if (dictSucc) {
					return success(symbol);
				} else {
					return error("更新字典数据,stockSymbolList失败;");
				}
			} else {
				return error(addErr);
			}

		} catch (e) {
			return error(e);
		}

	}
	// 获取symbolList
	async getStockSymbolList() {
		try {
			const pageSize = 500;
			const {
				total
			} = await STOCK_BASE_COLL.count();
			if (typeOf(total, StatusEnum.NUMBER)) {
				const symbolTotalList = [];
				const pageCount = Math.ceil(total / pageSize);
				for (let i = 0; i < pageCount; i++) {
					const {
						affectedDocs,
						data
					} = await STOCK_BASE_COLL.where({
						_id: dbCmd.exists(true)
					}).skip(i * pageSize).field({
						symbol: true
					}).limit(pageSize).get() || {};

					if (typeOf(affectedDocs, StatusEnum.NUMBER)) {
						const symbolList = data.map(i => i.symbol) || [];
						symbolTotalList.push(...symbolList);
					} else {
						return error("循环请求基金基本信息列表异常", i);
					}
				}
				return success(symbolTotalList);
			} else {
				return error("获取基金基本信息集合Total异常;", total);
			}

		} catch (e) {
			throw e
		}

	}
	async addStockSymbolListToDict() {
		try {
			const getStockSymbolListRes = await this.getStockSymbolList();
			const {
				success: symbolSucc,
				data: symbolList
			} = getStockSymbolListRes || {};
			if (symbolSucc && symbolList) {
				const {
					result,
					success
				} = await uniCloud.callFunction({
					name: "dictionary",
					data: {
						action: "common/addDictDataItem",
						data: new DictItem({
							type: "stockSymbolList",
							data: symbolList,
							name: "股票symbol列表",
							subjectCode: "stock",
							subjectName: "股票"
						})
					}
				}) || {};
				return result;
			} else {
				return getStockSymbolListRes;
			}

		} catch (e) {
			throw e
		}

	}
	async updateBaseInfoListWithStockById({
		docId = "",
		content = {}
	} = {}) {
		try {
			return await STOCK_BASE_COLL.doc(docId).update(content);
		} catch (e) {
			throw e
		}

	}
	async updateBaseInfoListWithStockByWhere({
		where = {},
		content = {}
	} = {}) {
		try {
			const {
				symbol
			} = content || {};
			const {
				updated
			} = await STOCK_BASE_COLL.where(where).update(content) || {};
			if (isNumber(updated)) {
				return success(symbol);
			} else {
				return error("stockBase集合添加数据异常;", symbol);
			}
		} catch (e) {
			return error("根据条件更新StockBase集合异常;", symbol);
		}

	}
	async removeAllOfBaseInfoListWithStock() {
		try {
			return await STOCK_BASE_COLL.where({
				_id: dbCmd.exists(true)
			}).remove();
		} catch (e) {
			throw e
		}

	}
	async getBaseInfoListWithStock({
		where = {},
		limit = 100,
		field = {},
		orderField = "_id",
		orderType = "asc",
	} = {}) {
		try {
			return await STOCK_BASE_COLL.where(where).limit(limit).orderBy(orderField, orderType).field(field)
				.get();
		} catch (e) {
			throw e
		}

	}
}
